Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Honor propery naming policy when (de)serializing KeyValuePair instances #1198

Closed
wants to merge 2 commits into from

Conversation

layomia
Copy link
Contributor

@layomia layomia commented Dec 28, 2019

Fixes #1197.

@layomia layomia added this to the 5.0 milestone Dec 28, 2019
@layomia layomia self-assigned this Dec 28, 2019
@layomia layomia force-pushed the keyvaluepair branch 2 times, most recently from 52422b1 to d452ef9 Compare December 28, 2019 03:21
@@ -125,6 +125,12 @@ public static void ThrowInvalidOperationException_SerializerPropertyNameNull(Typ
throw new InvalidOperationException(SR.Format(SR.SerializerPropertyNameNull, parentType, jsonPropertyInfo.PropertyInfo.Name));
}

[MethodImpl(MethodImplOptions.NoInlining)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NoInlining is not necessary on throw helpers like this. It actually degrades performance because it prevents the JIT from realizing that the throw helper never returns.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @steveharter, @ahsonkhan on the other helpers in this file.

@jkotas
Copy link
Member

jkotas commented Dec 28, 2019

Can this change break existing working code?

@layomia
Copy link
Contributor Author

layomia commented Dec 28, 2019

Can this change break existing working code?

Yes, it will break anyone depending on options.PropertyNamingPolicy not applying to KeyValuePair properties. We'd have to document this change, which fixes #1197.

@jkotas
Copy link
Member

jkotas commented Dec 28, 2019

It is not good enough to just document these breaking changes. The impact of each breaking change needs to be carefully evaluated. We do not want to end up in situation where people cannot upgrade to .NET 5 because of a ton of unmitigated breaking changes in System.Text.Json.

I believe that you will end up needing to come up with a plan how to make these behavior changes to be opt-in, so the code that works fine against .NET Core 3.x is going to keep working fine against .NET 5.

@NoneGiven
Copy link

@jkotas If a switch is needed, consider making this change the default and adding a documented opt-out switch. The behavior introduced by this PR brings things in line with user expectations, whereas before this was just a solitary rough edge that I can attest bites you in real-world scenarios. There are essentially no use cases for wanting the old behavior, besides of course maintaining compatibility when you already wrote code that expects that (buggy) behavior.

@layomia
Copy link
Contributor Author

layomia commented Dec 29, 2019

@steveharter proposed a new KeyValuePairNamingPolicy option, which if added, would be applied to this change to make it opt-in and non-breaking.

Given that KeyValuePair<,> is just a struct, the PropertyNamingPolicy really should be applied to its property names. If we go in this direction, I think there'd be great value in providing an easy way to opt-out of the breaking behavior, maybe a global boolean option.

In general for 5.0, the goal would be to make behavior changes opt-in, perhaps by providing an opt-in for each behavior change, and/or shared opt-ins for each cluster of related changes. In some cases, it may be difficult to justify why the change is not the default (besides being a breaking change), and we may need to take the break (and provide an easy way to opt out).

Marking this PR "no merge" as the change needs further investigation and consensus.

@layomia layomia added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Dec 29, 2019
@jkotas
Copy link
Member

jkotas commented Dec 29, 2019

justify why the change is not the default (besides being a breaking change)

We need to have data to be able to reason about this: Create database of System.Text.Json serialization uses and then evaluate the breaking changes like these against it. Our technical insights team should be able to help you with this.

I think there'd be great value in providing an easy way to opt-out of the breaking behavior, maybe a global boolean option.

A global switches like this tend to not work well as a solution. They affect all uses in your project, and so applying the switch will fix one use but can break another one. This is further complicated by the fact that number of these uses may be internal in packages that you depend on.

@layomia
Copy link
Contributor Author

layomia commented Jan 8, 2020

Our technical insights team should be able to help you with this.

👍

A global switches like this tend to not work well as a solution.

Not sure if this changes your position, but by "global boolean option", I meant an option on the JsonSerializerOptions class (which won't affect affect the entire project).

@jkotas
Copy link
Member

jkotas commented Jan 8, 2020

Not sure if this changes your position, but by "global boolean option", I meant an option on the JsonSerializerOptions class (which won't affect affect the entire project).

Yes, that would be fine. I would not call this global option. And I do not think it can be an opt-out. It has to be opt-in to be non-breaking so that the existing code that you do not own and are able to change continues to work.

@ArrowCase
Copy link

@jkotas This is a pretty bad bug to enshrine forever as default behavior, and code that depends on the buggy behavior will be vanishingly rare. The impact of an opt-out switch would just be that KVPs start round-tripping correctly when using camel case instead of throwing an exception on deserialization.

@jkotas
Copy link
Member

jkotas commented Jan 17, 2020

This is a pretty bad bug to enshrine forever as default behavior,

I won't disagree with this statement.

code that depends on the buggy behavior will be vanishingly rare.

This is fine hypothesis. I would like to see a plan for how we are going to collect data to confirm it for this change, and for number of other behavior changing changes that are proposed for System.Text.Json serializers.

@stephentoub
Copy link
Member

stephentoub commented Feb 17, 2020

@layomia, @ahsonkhan, where are we with this? If we're not ready to take it because we need to investigate breaking change potential, I'd prefer we close it and only open it again when it's actually ready to be "pulled". Thanks.

@layomia
Copy link
Contributor Author

layomia commented Feb 18, 2020

@stephentoub, we are still investigating breaking change potential. I'll close it and reopen when it's ready.

@layomia layomia closed this Feb 18, 2020
@layomia layomia added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Apr 17, 2020
@layomia
Copy link
Contributor Author

layomia commented Oct 15, 2020

Removing the breaking-change label since this was PR closed. #36424 made the changes proposed by this PR.

@layomia layomia removed the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Oct 15, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
@layomia layomia deleted the keyvaluepair branch May 18, 2021 07:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

KeyValuePair is not properly serialized with JsonNamingPolicy.CamelCase - System.Text.Json
5 participants